/* Copyright 2009 Requirements Management System 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mags.remas.view.dialogs;

import org.eclipse.swt.SWT;   
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Slider;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;

/**
 * 
 * @author Mario Gaitan
 *
 */
public abstract class AbstractDialog extends Shell {
	private Display display;
	private boolean firstTime=true;
	private KeyListener keyListener;
	private Control firstControl=null;
	public AbstractDialog(Display display, int style) {
        super(display, SWT.APPLICATION_MODAL|SWT.TITLE|SWT.BORDER|style);
        this.display = display;
        createPartControl(this);
        addKeyListener(this);
        pack(true);
        centerDialog();		
	}
	public void show() {
		show(null);
	}
    public void show(Control controlToFocus) {
    	if(firstTime) {
    		super.open();
    		firstTime = false;
    	}
    	else
    		super.setVisible(true);
    	if(controlToFocus==null)
    		firstControl.setFocus();
    	else
    		controlToFocus.setFocus();
    	block();
    }
    public void hide() {
    	super.setVisible(false);
    }
    public void close() {
    	//super.setVisible(false);
    	super.close();
    	super.dispose();
    }
    private void block() {
        while (!isDisposed()&&isVisible()) {
            if (!display.readAndDispatch()) { 
            	display.sleep();
            }
        }    	
    }
    private void centerDialog() {
        Rectangle screen = display.getPrimaryMonitor().getBounds();
        Rectangle window = getBounds();
        int x = screen.x + (screen.width-window.width)/2;
        int y = screen.y + (screen.height-window.height)/2;
        setLocation(x, y);                    	
    }
    @Override
    protected void checkSubclass () {
    }
    private KeyListener getKeyListener() {
    	if(keyListener==null) {
    		keyListener = new KeyListener() {
				@Override
				public void keyPressed(KeyEvent e) {
			    	if(e.keyCode==SWT.ESC)
			    		cancel();
			    	else if(e.keyCode==SWT.CR)
			    		accept();
				}
				@Override
				public void keyReleased(KeyEvent e) {
				}
	    	};
    	}
    	return keyListener;
    }    
    private boolean isValidControl(Control c) {
    	if(c instanceof Button
	    	|| c instanceof Canvas
	    	|| c instanceof Combo
	    	|| c instanceof DateTime
	    	|| c instanceof ExpandBar
	    	|| c instanceof Group
	    	|| c instanceof List
	    	|| c instanceof ProgressBar
	    	|| c instanceof Scale
	    	|| c instanceof Slider
	    	|| c instanceof Spinner
	    	|| c instanceof TabFolder
	    	|| c instanceof Table
	    	|| c instanceof Text
	    	|| c instanceof Tree
    	)
    		return true;
    	return false;
    }
    private void addKeyListener(Composite parent) {
    	for(Control c: parent.getChildren()) {
    		if(!((c.getStyle()&SWT.NO_FOCUS)==SWT.NO_FOCUS)&&isValidControl(c)) {
    			if(firstControl==null)
    				firstControl = c;
	    		c.addKeyListener(getKeyListener());
    		}
    		if(c instanceof Composite)
    			addKeyListener((Composite)c);
    	}
    }    
	protected abstract void createPartControl(Composite parent);
    public abstract void cancel();
    public abstract void accept();	
}
